#include "ml307.h"

#include "FreeRTOS.h"
#include "at_http_register.h"  //for urc callback
#include "queue.h"
#include "semphr.h"
#include "t_at.h"
#include "task.h"
// t_at_t 对象
t_at_t *ML307R;
// ML370MQTT配置
ml307_cfg_t ml307_cfg = {
    // 初始化网络信息
    .ml307_net_info_t =
        {
            .ip_4g = "0.0.0.0",               // 默认IP
            .net_name = "46000",              // 中国移动默认MNC+MCC
            .iccid = "89860000000000000000",  // 默认ICCID
            .imsi = "460000000000000",        // 默认IMSI
            .db_singal = 0                    // 默认信号强度
        },
				
		.ml307_reg_sta={
		  .sp_time=100,
		},
    // 初始化4个MQTT客户端配置
    .smqtt =
        {
            [0] =
                {// 第一个MQTT客户端
                 .ml307_mqtt_id = 0,
                 .ssl = 0,
                 .topic_mux = 0,  // 启用多主题
                 .txt_name = "MQTT_Client_0",
                 .client_id = "client_0",
                 .user_name = "user0",
                 .pass_word = "pass0",
                 .host = "broker.emqx.io",
                 .port = 1883,
                 .SubTopic =
                     {
                         [0] = {.subtopic = "topic0/sub1"},
                         [1] = {.subtopic = "topic0/sub2"},
                         [2] = {.subtopic = ""}  // 空主题
                     },
                 .PubTopic = "topic0/pub",
                 .Qos = 0},
            [1] =
                {// 第二个MQTT客户端
                 .ml307_mqtt_id = 1,
                 .ssl = 0,
                 .topic_mux = 0,  // 单主题
                 .txt_name = "MQTT_Client_1",
                 .client_id = "client_1",
                 .user_name = "user1",
                 .pass_word = "pass1",
                 .host = "ssl.example.com",
                 .port = 8883,
                 .SubTopic = {[0] = {.subtopic = "topic1/sub"},
                              [1] = {.subtopic = ""},
                              [2] = {.subtopic = ""}},
                 .PubTopic = "topic1/pub",
                 .Qos = 2},

        },

    // 设置启用的MQTT客户端数量
    .ml307_mqttc_num = 1  // 实际启用了前2个客户端
};

rbuf ml_ringbuf;
// freeRTOS 事件组(用于等待AT对象初始化完成)-----阻塞
static EventGroupHandle_t osEvent = NULL;

// 提供自动注册的API
void set_http_register_enable(uint8_t enable) {
    ml307_cfg.ml307_reg_sta.ml307_register_en = enable;
}
uint8_t get_http_register_enable(void) { return ml307_cfg.ml307_reg_sta.ml307_register_en; }
void set_http_register_status(uint8_t status) {
    ml307_cfg.ml307_reg_sta.ml307_register_sta = status;
}
uint8_t get_http_register_status(void) {
    return ml307_cfg.ml307_reg_sta.ml307_register_sta;  // 返回注册状态 0:未注册,2已注册
}
uint8_t get_ml307_mqttc_link(uint8_t mqttc_id) {
    return ml307_cfg.smqtt[mqttc_id].mqttc_link;  // 返回MQTT客户端连接状态
}
void set_ml307_mqttc_link(uint8_t mqttc_id, uint8_t link_status) {
    ml307_cfg.smqtt[mqttc_id].mqttc_link = link_status;  // 设置MQTT客户端连接状态为已连接
}

// typedef uint8_t (*t_at_send)(void *Ptx, uint8_t *dataBuf, uint16_t bufLen);实现这种形式
void ML307R_HW_SEND(t_at_send ml_send_cmd) {
    t_at_send_add(ML307R, ml_send_cmd);
    return;
}
void ML307R_PUSH_DATA(uint8_t *dataBuf, uint16_t data_len) {
    t_at_rev_push_data_rbf(ML307R, dataBuf, data_len, "+MQTTURC:");
    return;
}

uint8_t set_sptime(uint16_t time) {
    if (time < 100 || time > 5000) {
        return 0;  // 参数错误
    }
    ml307_cfg.ml307_reg_sta.sp_time=time;  // 设置AT发送时间
    return 1;                          // 成功
}
uint16_t get_sptime(void) {
   return ( ml307_cfg.ml307_reg_sta.sp_time)/1000;  // 获取AT发送时间
}
uint8_t ml307_send_cmd_callback(void *Ptx, uint8_t *dataBuf, uint8_t data_len,
                                uint8_t *cmd_Urc_String) {
    printf("cb%s\r\n", dataBuf);
    printf("slm_send_cmd handle callback OK.%s\r\n", cmd_Urc_String);
    return 0;
}
// 获取IP地址
/**
 * @brief 从AT命令响应中提取IPv4或IPv6地址
 * @param response AT命令响应字符串（例如 "+CGPADDR: 1,\"10.36.222.145\",\"2409:8D28...\"")
 * @param ip [out] 用于存储提取出的IP地址的缓冲区
 * @param ip_size ip缓冲区的大小（防止溢出）
 * @param get_ipv6 true提取IPv6，false提取IPv4
 * @return true提取成功，false提取失败
 * @note 典型响应格式：+CGPADDR: <cid>,"IPv4","IPv6"
 */
static bool ml_extract_ip(const char *response, char *ip, size_t ip_size, bool get_ipv6) {
    const char *start = strstr(response, "+CGPADDR:");
    if (!start) {
        return false;
    }

    const char *target_quote = NULL;
    if (get_ipv6) {
        target_quote = strchr(strchr(start, '"') + 1, '"');
    } else {
        target_quote = strchr(start, '"');
    }

    if (!target_quote) {
        return false;
    }

    start = target_quote + 1;
    const char *end = strchr(start, '"');
    if (!end || (end - start) >= ip_size) {
        return false;
    }

    /* 4. 安全拷贝IP地址 */
    strncpy(ip, start, end - start);

    return true;
}
// 获取注册运营商

/**
 * @brief 从AT响应中提取PLMN代码（如46000）
 * @param response AT响应字符串（如 "+COPS: 0,2,\"46000\",7"）
 * @param plmn_code 输出缓冲区（至少6字节）
 * @return true提取成功，false失败
 */
static bool ml_extract_plmn(const char *response, char *plmn_code) {
    // 参数检查
    if (!response || !plmn_code) return false;

    // 定位PLMN字段
    const char *start = strstr(response, "+COPS:");
    if (!start) return false;

    // 查找PLMN代码的开始引号
    start = strchr(start, '"');
    if (!start) return false;
    start++;  // 跳过引号

    // 查找结束引号
    const char *end = strchr(start, '"');
    if (!end || (end - start) >= 6) return false;  // PLMN最长5位+结束符

    // 提取PLMN代码
    strncpy(plmn_code, start, end - start);
    plmn_code[end - start] = '\0';
    return true;
}

/**
 * @brief 从 +ICCID 响应中提取ICCID（如 "898604D00123D0355157"）
 * @param response AT指令响应字符串（如 "+ICCID: 898604D00123D0355157\r\nOK"）
 * @param iccid 存储提取的ICCID的缓冲区（需确保足够大小，至少21字节）
 * @return ML_TRUE 提取成功，ML_FALSE 失败
 */
static bool ml_extract_iccid(const char *response, char *iccid) {
    const char *start = strstr(response, "+ICCID: ");
    if (!start) return ML_FALSE;

    start += strlen("+ICCID: ");
    const char *end = strpbrk(start, "\r\n");
    if (!end) end = start + strlen(start);

    size_t len = end - start;
    if (len == 0 || len >= 21) return ML_FALSE;

    strncpy(iccid, start, len);
    iccid[len] = '\0';
    return ML_TRUE;
}

/**
 * @brief 从 +CSQ 响应中提取RSSI（信号强度）
 * @param response AT指令响应字符串（如 "+CSQ: 29,99\nOK"）
 * @param rssi 存储提取的RSSI值（范围0-31，99表示无效）
 * @return ML_TRUE 提取成功，ML_FALSE 失败
 */
static bool ml_extract_rssi(const char *response, uint8_t *rssi) {
    if (!response || !rssi) return ML_FALSE;

    const char *start = strstr(response, "+CSQ: ");
    if (!start) return ML_FALSE;

    int tmp_rssi, tmp_ber;  // 临时变量用于sscanf
    if (sscanf(start, "+CSQ: %d,%d", &tmp_rssi, &tmp_ber) != 2) {
        return ML_FALSE;  // 格式不匹配
    }

    // 验证RSSI范围（0-31或99）
    if (tmp_rssi < 0 || (tmp_rssi > 31 && tmp_rssi != 99)) {
        return ML_FALSE;
    }

    *rssi = (uint8_t)tmp_rssi;  // 安全转换
    return ML_TRUE;
}

/**
 * @brief 从响应字符串中提取IMSI（如 "460085039505157"）
 * @param response AT指令响应字符串（如 "460085039505157\nOK"）
 * @param imsi 存储提取的IMSI的缓冲区（需至少16字节）
 * @return ML_TRUE 提取成功，ML_FALSE 失败
 */
static bool ml_extract_imsi(const char *response, char *imsi) {
    if (!response || !imsi) return ML_FALSE;

    const char *start = response;
    while (*start && !isdigit((unsigned char)*start)) {
        start++;  // 跳过非数字前缀
    }

    if (!*start) return ML_FALSE;  // 无数字

    const char *end = start;
    while (*end && isdigit((unsigned char)*end)) {
        end++;  // 定位数字结尾
    }

    size_t len = end - start;
    if (len != 15) return ML_FALSE;  // IMSI必须为15位

    strncpy(imsi, start, len);
    imsi[len] = '\0';
    return ML_TRUE;
}
uint8_t ml307_send_qact_cmd_callback(void *Ptx, uint8_t *dataBuf, uint8_t data_len,
                                     uint8_t *cmd_Urc_String) {
    // printf("cmd:%s  len=%d\r\n",dataBuf,data_len);
    ml_extract_ip((char *)dataBuf, ml307_cfg.ml307_net_info_t.ip_4g,
                  sizeof(ml307_cfg.ml307_net_info_t.ip_4g), false);
    return 0;
}
uint8_t ml307_send_cops_cmd_callback(void *Ptx, uint8_t *dataBuf, uint8_t data_len,
                                     uint8_t *cmd_Urc_String) {
    ml_extract_plmn((char *)dataBuf, ml307_cfg.ml307_net_info_t.net_name);
    return 0;
}
uint8_t ml307_send_ccid_cmd_callback(void *Ptx, uint8_t *dataBuf, uint8_t data_len,
                                     uint8_t *cmd_Urc_String) {
    ml_extract_iccid((char *)dataBuf, ml307_cfg.ml307_net_info_t.iccid);
    return 0;
}
uint8_t ml307_send_csq_callback(void *Ptx, uint8_t *dataBuf, uint8_t data_len,
                                uint8_t *cmd_Urc_String) {
    ml_extract_rssi((char *)dataBuf, &ml307_cfg.ml307_net_info_t.db_singal);
    return 0;
}
uint8_t ml307_send_imsi_cmd_callback(void *Ptx, uint8_t *dataBuf, uint8_t data_len,
                                     uint8_t *cmd_Urc_String) {
    ml_extract_imsi((char *)dataBuf, ml307_cfg.ml307_net_info_t.imsi);
    return 0;
}

uint8_t ml307_Opean_callback(void *Ptx, uint8_t *dataBuf, uint8_t data_len,
                             uint8_t *cmd_Urc_String) {
    printf("ml307_opean_callback handle OK  . %s\n", cmd_Urc_String);
    return 0;
}
uint8_t ml307_send_callback(void *Ptx, uint8_t *dataBuf, uint8_t data_len,
                            uint8_t *cmd_Urc_String) {
    printf("ml307_send_callback handle OK  . %s\n", cmd_Urc_String);
    return 0;
}
// 处理MQTTLINK的CB_handle
uint8_t ml307_mqtt_callback(void *Ptx, uint8_t *dataBuf, uint8_t data_len, uint8_t *cmd_Urc_String) {
   char *response = (char*)dataBuf;
   char *ptr;
	//printf("cmd1%s\n", dataBuf);
	//printf("cmd2%s\n", cmd_Urc_String);
	if((ptr = strstr(response, "+MQTTSTATE:")) != NULL) {
        // 跳过"+MQTTSTATE:"部分
        ptr += strlen("+MQTTSTATE:");
        // 跳过可能的空格
        while(*ptr == ' ') ptr++;
        
        // 转换为数字
        uint8_t state = (uint8_t)atoi(ptr);
        printf("Extracted MQTT state: %u\n", state);
        set_ml307_mqttc_link(0,state);
        return state; // 返回状态值
    }
    return 0;
}

extern UART_HandleTypeDef ml_huart4;

// 硬件接口(实际的发送函数)
uint8_t ml_send_cmd(void *Ptx, uint8_t *dataBuf, uint16_t bufLen) {
    HAL_UART_Transmit(&ml_huart4, dataBuf, bufLen, 1000);
    return 0;
}

/**
 * @brief  发送AT命令到ML307模块并等待响应
 * @param CMD 要发送的AT命令字符串
 * @param Data_len 要发送的AT命令长度
 * @param CMD_UCR 预期的响应字符串
 * @param Phandle 响应处理函数的回调函数
 * @param waittime 等待响应的时间（单位：毫秒）
 * @param resendCount 重试发送的次数
 * @return slm_error_t 返回发送结果的状态
 * @note: 该函数会阻塞等待响应，直到超时或收到预期的响应并且封装了
 * t_at_t 对象  t_at_t *ML307R=NULL;
 */
ml307_error_t ml307_send_cmd(char *CMD,                   //
                             uint16_t Data_len,           //
                             char *CMD_UCR,               //
                             t_at_urc_callback Phandle,   //
                             uint32_t waittime,           //
                             uint8_t resendCount          //
) {
    T_ErrType ret;
    ret = t_at_cmd_send(ML307R, Data_len, CMD, CMD_UCR, Phandle, waittime, resendCount);
    if (ret == AT_OK) {
        return ml_send_ok;
    } else {
        return ml_send_fail;
    }
}
/**
 * @brief  ML307模块的电源控制函数
 */
void ml307_power_gpio_set(void) {
	 GPIO_InitTypeDef GPIO_InitStruct = {0};

	 /* GPIO Ports Clock Enable */
	 __HAL_RCC_GPIOD_CLK_ENABLE();
	 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);
	 /*Configure GPIO pin : PD15 */
	 GPIO_InitStruct.Pin = GPIO_PIN_15;
	 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	 GPIO_InitStruct.Pull = GPIO_PULLUP;
	 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	 HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
	 // 开机管脚动作
	 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_RESET);
	 vTaskDelay(5000);//直接拉低永久开机
//	 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);
//	 vTaskDelay(5000);  // 10s开机
}

ml307_error_t ml_power_open(void)  // 开机
{
    char temp[20];
    ml307_error_t ret;
    ml307_power_gpio_set();
    snprintf(temp, sizeof(temp), "AT\r\n");
    int len = strlen(temp);
    ret = ml307_send_cmd(temp, len, "OK", ml307_Opean_callback, 1000, 2);
    return ret;
}
// 开机ml307模块
ml307_error_t ml_do_ml307_powr_open_ok(uint8_t do_work_re) {
    ml307_error_t ret;
    uint8_t retry_count = 0;
    do {
        ret = ml_power_open();
        if (ret == ml_send_fail) {
            retry_count++;
        } else {
            break;
        }
    } while (retry_count < do_work_re);

    if (retry_count == do_work_re) {
        return ml_powr_open_fail;  // 开机失败
    }

    return ml_powr_open_ok;
}

uint8_t get_ml307_mqttc_number(void) { return ml307_cfg.ml307_mqttc_num; }
uint8_t at_delay(uint32_t t_delay_counts) {
    vTaskDelay(t_delay_counts);
    return 1;
}
extern void set_ml307_mqtt_setup(uint8_t setup) { ml307_cfg.ml307_mqttc_num = setup; }
//////////////创建MQTT连接的守护进程///////////
void mqtt_sta(void *prame);
SemaphoreHandle_t xBinarySemaphore;
void sta_init(void) {
    xBinarySemaphore = xSemaphoreCreateBinary();
    xTaskCreate(mqtt_sta, "mqsta", 256, NULL, 1, NULL);
}
void mqtt_sta(void *prame) {
    char *tmp_cmd = AT_MALLOC(200);
    uint16_t tmp_cmd_len = 200;
    uint16_t len = 0;
    while (1) {
        AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd, tmp_cmd_len, &len,"AT+MQTTSTATE=0");
        //printf("cmd:%s\r\n", tmp_cmd);
        ml307_send_cmd(tmp_cmd, len, "+MQTTSTATE:", ml307_mqtt_callback, 1000, 2);
        vTaskDelay(10000);  // 添加适当延迟
    }
}
#include "j_parm_a.h"  //for mac
ml307_error_t ml370_creat(ml307_cfg_t *ml307_cfg) {
    ml307_cfg->ml307_reg_sta.ml307_register_en = 1;//test
    // 初始化ML307_MQTT配置
    set_ml307_mqtt_setup(1);  // 你需要创建多少个MQTTC(max 6)

    if (ml307_cfg == NULL) {
        return ml_error;
    }
    // 动态申请内存
    char *tmp_cmd = AT_MALLOC(200);
    uint16_t tmp_cmd_len = 200;
    char *MAC_ptr = AT_MALLOC(50);
    EventGroupHandle_t *osEvent = AT_MALLOC(sizeof(EventGroupHandle_t));
    if (!tmp_cmd || !osEvent) {
        AT_FREE(tmp_cmd);
        AT_FREE(osEvent);
        return ml_error;
    }

    // 初始化AT对象
    ML307R = t_at_create(T_NULL, ml307_send_callback, 100, 1);
    if (ML307R == NULL) {
        AT_FREE(tmp_cmd);
        AT_FREE(osEvent);
        return ml_error;
    }
    ML307R_HW_SEND(ml_send_cmd);//添加
    // 创建OS锁和循环队列
    t_at_os_add(ML307R, osEvent, t_at_os_init_t, t_at_os_lock_t, t_at_os_unlock_t);
    t_at_ringbuffer_add(ML307R, &ml_ringbuf, rbuf_init, rbuf_push, rbuf_pop, rbuf_clear,
                        rbuf_is_empty, rbuf_is_full);
    t_at_urc_ringbuffer_add(ML307R, &urc_rbuf);     // 添加URC环形缓冲区
    t_at_set_URC_userarg(ML307R, &rev_mqttc_info);  // 设置URC回调函数
    at_urc_thread_init(ML307R);
    t_at_delay_add(ML307R, at_delay);  // 初始化URC处理线程

    // 开机模块并检查状态
    ml307_error_t ret = ml_do_ml307_powr_open_ok(2);
    if (ret == ml_send_fail) {
        ml307_cfg->ml307_status = ml_power_down;
        AT_FREE(tmp_cmd);
        AT_FREE(osEvent);
        return ml_powr_open_ok;  // 开机失败
    }
		
    // 自动注册(注册和应用是异步分开的)
    if (ml307_cfg->ml307_reg_sta.ml307_register_en == 1) {  // 如果启用自动注册打开

        sprintf(MAC_ptr, "%x:%x:%x:%x:%x:%x", sys_cfg.mac[0], sys_cfg.mac[1],
                sys_cfg.mac[2],  // 拿到system MAC
                sys_cfg.mac[3], sys_cfg.mac[4], sys_cfg.mac[5]);
        at_http_register_init(MAC_ptr, 164);  // 164是创建的产品类型
    } else {
        ml307_cfg->ml307_reg_sta.ml307_register_en = 0;  // 禁用自动注册
    }
    t_at_send_time_set(ML307R, 100);  // 设置指令间隔时间

    uint16_t len = 0;
    // 发送AT指令
    AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd, tmp_cmd_len, &len, "AT");
    printf("cmd:%s\r\n", tmp_cmd);
    ret = ml307_send_cmd(tmp_cmd, len, "OK", ml307_send_callback, 1000, 2);
    // 激活PDP
    AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd, tmp_cmd_len, &len, "AT+CGATT=%d", 1);
    printf("cmd:%s\r\n", tmp_cmd);
    ret = ml307_send_cmd(tmp_cmd, len, "OK", ml307_send_callback, 1000, 2);

    AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd, tmp_cmd_len, &len, "AT+CGACT=%d,%d", 1, 1);
    printf("cmd:%s\r\n", tmp_cmd);
    ret = ml307_send_cmd(tmp_cmd, len, "OK", ml307_send_callback, 1000, 2);
    // 获取IP地址
    AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd, tmp_cmd_len, &len, "AT+CGPADDR=1");
    printf("cmd:%s\r\n", tmp_cmd);
    ret = ml307_send_cmd(tmp_cmd, len, "+CGPADDR:", ml307_send_qact_cmd_callback, 1000, 2);

    // 获取运营商信息
    AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd, tmp_cmd_len, &len, "AT+COPS=3,2; +COPS?");
    printf("cmd:%s\r\n", tmp_cmd);
    ret = ml307_send_cmd(tmp_cmd, len, "+COPS:", ml307_send_cops_cmd_callback, 1000, 2);
    // 获取SIM卡的ICCID
    AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd, tmp_cmd_len, &len, "AT+ICCID");
    printf("cmd:%s\r\n", tmp_cmd);
    ret = ml307_send_cmd(tmp_cmd, len, "+ICCID:", ml307_send_ccid_cmd_callback, 1000, 2);
    // 获取信号强度
    AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd, tmp_cmd_len, &len, "AT+CSQ");
    printf("cmd:%s\r\n", tmp_cmd);
    ret = ml307_send_cmd(tmp_cmd, len, "+CSQ:", ml307_send_csq_callback, 1000, 2);
    // 获取IMSI
    AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd, tmp_cmd_len, &len, "AT+CIMI");
    printf("cmd:%s\r\n", tmp_cmd);
    ret = ml307_send_cmd(tmp_cmd, len, "OK", ml307_send_imsi_cmd_callback, 1000, 2);

    // MQTT应用CFG
    for (int i = 0; i < get_ml307_mqttc_number(); i++) {
        AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd, tmp_cmd_len, &len, "AT+MQTTDISC=%d", i);
        ret = ml307_send_cmd(tmp_cmd, len, "OK", ml307_send_callback, 1000, 2);

        AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd, tmp_cmd_len, &len, "AT+MQTTCFG=\"version\",%d,%d", i, 4);
        printf("cmd:%s\r\n", tmp_cmd);
        ret = ml307_send_cmd(tmp_cmd, len, "OK", ml307_send_callback, 1000, 2);

        AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd, tmp_cmd_len, &len, "AT+MQTTCFG=\"pingreq\",%d,%d", i, 60);
        printf("cmd:%s\r\n", tmp_cmd);
        ret = ml307_send_cmd(tmp_cmd, len, "OK", ml307_send_callback, 1000, 2);
        if (ml307_cfg->smqtt[i].ssl == 1) {  // 如果启用加密连接采用加密连接
            AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd, tmp_cmd_len, &len, "AT+MQTTCFG=\"ssl\",%d,%d", i, 1);
            printf("cmd:%s\r\n", tmp_cmd);
            ret = ml307_send_cmd(tmp_cmd, len, "OK", ml307_send_callback, 1000, 2);
        }
    }
    // 连接MQTT服务器
    for (int i = 0; i < get_ml307_mqttc_number(); i++) {
        // AT+MQTTCONN=<connect_id>,<host>[,<port>[,<clientID>,<user>,<passwd>]]
        AT_CMD_FORMAT_AUTO_CRLF(
            tmp_cmd, tmp_cmd_len, &len, "AT+MQTTCONN=%d,\"%s\",%d,\"%s\",\"%s\",\"%s\"", i,
            ml307_cfg->smqtt[i].host, ml307_cfg->smqtt[i].port, ml307_cfg->smqtt[i].client_id,
            ml307_cfg->smqtt[i].user_name, ml307_cfg->smqtt[i].pass_word);
        printf("cmd:%s\r\n", tmp_cmd);

        ret = ml307_send_cmd(tmp_cmd, len, "OK", ml307_send_callback, 1000, 2);
        //  AT+MQTTSUB=<connect_id>,<topic>,<qos>[,<topic1>,<qos1>..]
        if (ml307_cfg->smqtt[i].topic_mux == 1) {  // 多主体
           vTaskDelay(3000);
            AT_CMD_FORMAT_AUTO_CRLF(
                tmp_cmd, tmp_cmd_len, &len, "AT+MQTTSUB=%d,\"%s\",%d,\"%s\",%d,\"%s\",%d", i,
                ml307_cfg->smqtt[i].SubTopic[0].subtopic, ml307_cfg->smqtt[i].Qos,
                ml307_cfg->smqtt[i].SubTopic[1].subtopic, ml307_cfg->smqtt[i].Qos,
                ml307_cfg->smqtt[i].SubTopic[2].subtopic, ml307_cfg->smqtt[i].Qos);
            printf("cmd_mux:%s\r\n", tmp_cmd);
            ret = ml307_send_cmd(tmp_cmd, len, "OK", ml307_send_callback, 1000, 2);
        } else {  // 单主题
					  AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd, tmp_cmd_len, &len, "AT");
            printf("cmd:%s\r\n", tmp_cmd);
            ret = ml307_send_cmd(tmp_cmd, len, "OK", ml307_send_callback, 1000, 2);
					  vTaskDelay(3000);
            AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd, tmp_cmd_len, &len, "AT+MQTTSUB=%d,\"%s\",%d", i,
                                    ml307_cfg->smqtt[i].SubTopic[0].subtopic,
                                    ml307_cfg->smqtt[i].Qos);
            printf("cmd_s:%s\r\n", tmp_cmd);
            ret = ml307_send_cmd(tmp_cmd, len, "OK", ml307_send_callback, 1000, 2);

            // Add subscription verification with retry logic
            int retry_count = 0;
            const int max_retries = 2;
            bool subscription_confirmed = false;

            while (retry_count < max_retries && !subscription_confirmed) {
                // Check if subscription was successful
                AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd, tmp_cmd_len, &len, "AT+MQTTSUB=%d", i);
                printf("cmd_s:%s\r\n", tmp_cmd);
                ret = ml307_send_cmd(tmp_cmd, len, "+MQTTSUB:", ml307_send_callback, 1000, 2);

                if (ret == ml_send_fail) {
                    printf("Subscription verification failed, retrying (%d/%d)...\n",
                           retry_count + 1, max_retries);

                    // Resend the subscription command
                    AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd, tmp_cmd_len, &len, "AT+MQTTSUB=%d,\"%s\",%d",
                                            i, ml307_cfg->smqtt[i].SubTopic[0].subtopic,
                                            ml307_cfg->smqtt[i].Qos);
                    printf("cmd_s:%s\r\n", tmp_cmd);
                    ret = ml307_send_cmd(tmp_cmd, len, "OK", ml307_send_callback, 1000, 2);

                    retry_count++;
                } else {
                    subscription_confirmed = true;
                    printf("Subscription verified successfully.\n");
                }
            }

            if (!subscription_confirmed) {
                printf("Warning: Subscription not confirmed after %d attempts. Continuing...\n",
                       max_retries);
            }
        }
    }
    vTaskDelay(1000);
    AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd, tmp_cmd_len, &len, "AT+MQTTPUB=0,\"ppjia\",0,0,0,4,\"3242\"");
    printf("cmd:%s\r\n", tmp_cmd);
    ret = ml307_send_cmd(tmp_cmd, len, "OK", ml307_send_callback, 1000, 2);
		sta_init();//创建守护线程
    // 释放临时缓冲区
    AT_FREE(tmp_cmd);
    AT_FREE(MAC_ptr);
    return ret;
}

/**
 * @brief 发送数据到MQTT服务器
 * @param ml ML307对象
 * @param slm_cfg SLM配置
 * @param mqttc_id_t MQTT客户端ID
 * @param slm_send_callback 发送回调函数
 * @param data 要发送的数据
 * @param datalen 数据长度
 * @return 发送结果
 * @note 该函数会阻塞等待响应，直到超时或收到预期的响应
 */
char ml_tmp_cmd[300];
ml307_error_t ml307_send_net_data(t_at_t *ml, ml307_cfg_t *slm_cfg, uint8_t mqttc_id_t,
                                  t_at_urc_callback slm_send_callback, char *data,
                                  uint16_t datalen) {
    ml307_error_t ret = ml_send_fail;
    uint16_t len;
    t_at_send_time_set(ml, 100);
    // AT+MQTTPUB=<connect_id>,<topic>,<qos>,<retain>,<dup>,<msg_len>[,<message>].
    AT_CMD_FORMAT_AUTO_CRLF(ml_tmp_cmd, 300, &len, "AT+MQTTPUB=%d,\"%s\",%d,0,0,%d",
                            mqttc_id_t, slm_cfg->smqtt[mqttc_id_t].PubTopic,
                            slm_cfg->smqtt[mqttc_id_t].Qos, datalen);
    printf("cmd11111:%s\r\n", ml_tmp_cmd);  // 调试打印，不用注掉
    ret = ml307_send_cmd(ml_tmp_cmd, len, ">", ml307_send_callback, 1000, 1);
																		
		ret = ml307_send_cmd(data, datalen, "OK", ml307_send_callback, 1000, 1);																
    return ret;
}

//////////////////////////外部调用接口发送到云端//////////////////////////////

// 最大支持4路直接发送(存储的空间不够)
void ml_send1(char *data, uint16_t len) {
    ml307_send_net_data(ML307R, &ml307_cfg, 0, NULL, (char *)data, len);
}
void ml_send2(char *data, uint16_t len) {
    ml307_send_net_data(ML307R, &ml307_cfg, 1, NULL, (char *)data, len);
}
void ml_send3(char *data, uint16_t len) {
    ml307_send_net_data(ML307R, &ml307_cfg, 2, NULL, (char *)data, len);
}
void ml_send4(char *data, uint16_t len) {
    ml307_send_net_data(ML307R, &ml307_cfg, 3, NULL, (char *)data, len);
}

/**
 *  @brief 直接发送数据到MQTTT
 *  @note: 会照成阻塞（建议使用队列）
 */
#include "ml307_thread.h"
#include "j_modbus_a.h" //for j_modbus_recv_cb
/*MODBUS 接收数据 reply*/
//extern int fc_ad_modbus_recv_cb(void *ctx, void* data, uint16_t len, MODBUS_PROTO_E proto, j_modbus_send send_func);

extern void uart1_send(void *data, uint16_t count);
// eg:usart-->boker
uint16_t bin_to_hex(uint8_t *bin, size_t len, char *out) {
    for (size_t i = 0; i < len; i++){ 
        sprintf(out + i*2, "%02X", bin[i]);
		}
		out[len*2] = '\0';
		return len*2;
	
}
void ml_mqttc_sned_net_channle_1(uint8_t id, char *data, uint16_t len) {
//	  char hex_buf[256];
//	  uint16_t hexlen=0;
//	  hexlen= bin_to_hex((uint8_t *)data, len, hex_buf); // 实现bin转支付串
		queue_ML_send1((uint8_t *)data, len);//上传云端
	  //ml_send1(data,len);

}

void ml_mqttc_sned_net_channle_2(uint8_t id, char *data, uint16_t len) {
    // queue_ML_send2((uint8_t *)data, len);
    printf("cmd%s....%d\r\n", data, len);
    ml_send2(data, len);
}

void ml_mqttc_sned_net_channle_3(uint8_t id, char *data, uint16_t len) {
    // queue_ML_send3((uint8_t *)data, len);
    printf("cmd%s....%d\r\n", data, len);
    ml_send3(data, len);
}

void ml_mqttc_sned_net_channle_4(uint8_t id, char *data, uint16_t len) {
    // queue_ML_send4((uint8_t *)data, len);
    printf("cmd%s....%d\r\n", data, len);
    ml_send4(data, len);
}
///构造uint16_t j_modbus_slave_mg_send_func(void* ctx, void *arg, const uint8_t *req, int req_length)
uint16_t j_modbus_slave_ml_send_func(void* ctx, void *arg, const uint8_t *req, int req_length){
  ml_mqttc_sned_net_channle_1(1,( char *)req,req_length);
	return req_length;
}

/// 云端MQTT4路发送的  mqtt brokr----->uart
void ml_mqttc_sned_other_interface_1(char *data, uint16_t len) {
	 //printf("cmd%s....%d\r\n", data, len);
   //fc_ad_modbus_recv_cb((void*)0xfc,data,len,MODBUS_PROTO_RTU,j_modbus_slave_ml_send_func);
	  
}
void ml_mqttc_sned_other_interface_2(char *data, uint16_t len) {
    /*
     *发送的数据
     */
    // to_send();
    //	  	printf("hex: ");
    //     for (int i = 0; i < len; i++) {
    //        printf("%02X ", data[i]); // 每个字节用2位大写十六进制表示，空格分隔
    //    }
    //     printf(", len=%d\r\n", len);
    //ml_mqttc_sned_net_channle_2(1, data, len);
}
void ml_mqttc_sned_other_interface_3(char *data, uint16_t len) {
    /*
     *发送的数据
     */
    // to_send();
    //ml_mqttc_sned_net_channle_3(1, data, len);
    //	printf("data:%s, len=%d\r\n",data, len);
}
void ml_mqttc_sned_other_interface_4(char *data, uint16_t len) {
    /*
     *发送的数据
     */
    // to_send();
    //		  	printf("hex: ");
    //     for (int i = 0; i < len; i++) {
    //        printf("%02X ", data[i]); // 每个字节用2位大写十六进制表示，空格分隔
    //    }
    //     printf(", len=%d\r\n", len);
    //ml_mqttc_sned_net_channle_4(1, data, len);
}

// 带缓冲区
/*MG-modbus test*/
/*
 *MQTT解析发送到modbus
 *   : slm332  t_at_t 框架句柄
 *   : urc_func  匹配成功后进行回调  在这里实现replay
 *   : URC_info  要匹配字符串匹配成功后进行回调
 */
ml307_error_t ml_mqtt_modbus_urc_decode(t_at_t *AT, t_at_urc_callback urc_func, uint8_t *URC_info) {
    t_at_urc_callback_set(AT, urc_func);
    t_at_parse_polling_rbf(AT, URC_info);
    return ml_send_ok;
}
// 设置MQTT服务器地址
/**
 * @brief 设置MQTT指定客户端 服务器地址()
 * @param mqttc_id MQTT客户端ID
 * @param dev_info 设备信息指针
 * @param server_addr 服务器地址字符串
 */
mqttc_error_t ml307_set_mqttc_host(uint8_t mqttc_id, void *dev_info, char *host) {
    if (host == NULL || dev_info == NULL) {
        return mqt_param_null;  // 参数为空
    }
    ml307_cfg_t *cfg = (ml307_cfg_t *)dev_info;
    // 检查MQTT客户端ID范围 0-3
    if (mqttc_id >= cfg->ml307_mqttc_num) {
        return mqt_typedef_id;  // ID错误
    }
    // 安全复制服务器地址
    strncpy(cfg->smqtt[mqttc_id].host, host, sizeof(cfg->smqtt[mqttc_id].host) - 1);
    cfg->smqtt[mqttc_id].host[sizeof(cfg->smqtt[mqttc_id].host) - 1] = '\0';  // 确保字符串终止
    return mqt_ok;
}
/**
 * @brief 设置MQTT服务器端口
 * @param mqttc_id MQTT客户端ID
 * @param dev_info 设备信息指针
 * @param port 服务器端口号
 */
mqttc_error_t ml307_set_mqttc_port(uint8_t mqttc_id, void *dev_info, int port) {
    if (dev_info == NULL) {
        return mqt_param_null;  // 参数为空
    }
    ml307_cfg_t *cfg = (ml307_cfg_t *)dev_info;
    // 检查MQTT客户端ID范围 0-3
    if (mqttc_id >= cfg->ml307_mqttc_num) {
        return mqt_typedef_id;  // ID错误
    }
    // 设置端口号
    cfg->smqtt[mqttc_id].port = port;
    return mqt_ok;
}

mqttc_error_t ml307_set_mqttc_client_id(uint8_t mqttc_id, void *dev_info, char *client_id) {
    if (client_id == NULL || dev_info == NULL) {
        return mqt_param_null;  // 参数为空
    }
    ml307_cfg_t *cfg = (ml307_cfg_t *)dev_info;
    // 检查MQTT客户端ID范围 0-3
    if (mqttc_id >= cfg->ml307_mqttc_num) {
        return mqt_typedef_id;  // ID错误
    }
    // 安全复制客户端ID
    strncpy(cfg->smqtt[mqttc_id].client_id, client_id, sizeof(cfg->smqtt[mqttc_id].client_id) - 1);
    cfg->smqtt[mqttc_id].client_id[sizeof(cfg->smqtt[mqttc_id].client_id) - 1] =
        '\0';  // 确保字符串终止
    return mqt_ok;
}
/**
 * @brief 设置MQTT客户端用户名
 * @param mqttc_id MQTT客户端ID
 * @param dev_info 设备信息指针
 * @param mqttc_userName 用户名字符串
 */
mqttc_error_t ml307_set_mqttc_user_name(uint8_t mqttc_id, void *dev_info, char *User_name) {
    if (User_name == NULL || dev_info == NULL) {
        return mqt_param_null;  // 参数为空
    }
    ml307_cfg_t *cfg = (ml307_cfg_t *)dev_info;
    // 检查MQTT客户端ID范围 0-3
    if (mqttc_id >= cfg->ml307_mqttc_num) {
        return mqt_typedef_id;  // ID错误
    }
    // 安全复制用户名
    strncpy(cfg->smqtt[mqttc_id].user_name, User_name, sizeof(cfg->smqtt[mqttc_id].user_name) - 1);
    cfg->smqtt[mqttc_id].user_name[sizeof(cfg->smqtt[mqttc_id].user_name) - 1] =
        '\0';  // 确保字符串终止
    return mqt_ok;
}
// 设置MQTT密码
mqttc_error_t ml307_set_mqttc_password(uint8_t mqttc_id, void *dev_info, char *pass_word) {
    if (pass_word == NULL || dev_info == NULL) {
        return mqt_param_null;  // 参数为空
    }
    ml307_cfg_t *cfg = (ml307_cfg_t *)dev_info;
    // 检查MQTT客户端ID范围 0-3
    if (mqttc_id >= cfg->ml307_mqttc_num) {
        return mqt_typedef_id;  // ID错误
    }
    // 安全复制密码
    strncpy(cfg->smqtt[mqttc_id].pass_word, pass_word, sizeof(cfg->smqtt[mqttc_id].pass_word) - 1);
    cfg->smqtt[mqttc_id].pass_word[sizeof(cfg->smqtt[mqttc_id].pass_word) - 1] =
        '\0';  // 确保字符串终止

    return mqt_ok;
}
// 设置订阅主题
/**
 * @brief 设置MQTT订阅主题(仅支持单个订阅主题)
 * @param mqttc_id MQTT客户端ID(deault:0)
 * @param dev_info 设备信息指针
 * @param mqttc_subTopic 订阅主题字符串
 */
mqttc_error_t ml307_set_mqttc_subscribe_topic(uint8_t mqttc_id, void *dev_info,
                                              char *mqttc_subTopic) {
    if (mqttc_subTopic == NULL || dev_info == NULL) {
        return mqt_param_null;  // 参数为空
    }
    ml307_cfg_t *cfg = (ml307_cfg_t *)dev_info;
    // 检查MQTT客户端ID范围 0-3
    if (mqttc_id >= cfg->ml307_mqttc_num) {
        return mqt_typedef_id;  // ID错误
    }
    // 安全复制订阅主题
    strncpy(cfg->smqtt[mqttc_id].SubTopic[0].subtopic, mqttc_subTopic,
            sizeof(cfg->smqtt[mqttc_id].SubTopic[0].subtopic) - 1);
    cfg->smqtt[mqttc_id]
        .SubTopic[0]
        .subtopic[sizeof(cfg->smqtt[mqttc_id].SubTopic[0].subtopic) - 1] = '\0';  // 确保字符串终止
    return mqt_ok;
}
// 设置发布主题
mqttc_error_t ml307_set_mqttc_publish_topic(uint8_t mqttc_id, void *dev_info,
                                            char *mqttc_pubTopic) {
    if (mqttc_pubTopic == NULL || dev_info == NULL) {
        return mqt_param_null;  // 参数为空
    }
    ml307_cfg_t *cfg = (ml307_cfg_t *)dev_info;
    // 检查MQTT客户端ID范围 0-3
    if (mqttc_id >= cfg->ml307_mqttc_num) {
        return mqt_typedef_id;  // ID错误
    }
    // 安全复制发布主题
    strncpy(cfg->smqtt[mqttc_id].PubTopic, mqttc_pubTopic,
            sizeof(cfg->smqtt[mqttc_id].PubTopic) - 1);
    cfg->smqtt[mqttc_id].PubTopic[sizeof(cfg->smqtt[mqttc_id].PubTopic) - 1] =
        '\0';  // 确保字符串终止
    return mqt_ok;
}
mqttc_error_t ml307_set_mqttc_ssl(uint8_t mqttc_id, void *dev_info, uint8_t ssl_enable) {
    if (dev_info == NULL) {
        return mqt_param_null;  // 参数为空
    }
    ml307_cfg_t *cfg = (ml307_cfg_t *)dev_info;
    // 检查MQTT客户端ID范围 0-3
    if (mqttc_id >= cfg->ml307_mqttc_num) {
        return mqt_typedef_id;  // ID错误
    }
    // 设置SSL标志
    cfg->smqtt[mqttc_id].ssl = ssl_enable;
    return mqt_ok;
}
mqttc_error_t ml307_set_mqttc_topic_mux(uint8_t mqttc_id, void *dev_info, uint8_t topic_mux) {
    if (dev_info == NULL) {
        return mqt_param_null;  // 参数为空
    }
    ml307_cfg_t *cfg = (ml307_cfg_t *)dev_info;
    // 检查MQTT客户端ID范围 0-3
    if (mqttc_id >= cfg->ml307_mqttc_num) {
        return mqt_typedef_id;  // ID错误
    }
    // 设置主题复用标志
    cfg->smqtt[mqttc_id].topic_mux = topic_mux;
    return mqt_ok;
}